<template>
    <zt-dialog v-model="visible" :title="titleName" @confirm="confirmBtn" :loading="isLoading" :showFooter="true"
        :showFullScreen="false" width="700px" height="600px" :showConfirm="!isDisabled">
        <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="80px" class="demo-ruleForm" status-icon
            :disabled="isDisabled">
            <el-form-item label="用户名称" prop="userName">
                <el-input v-model.trim="ruleForm.userName" placeholder="请输入用户名称" />
            </el-form-item>

            <el-form-item label="手机号" prop="mobile">
                <el-input v-model.trim="ruleForm.mobile" placeholder="请输入手机号" />
            </el-form-item>
            <el-form-item label="登录账号" prop="accountName">
                <el-input v-model.trim="ruleForm.accountName" placeholder="请输入登录账号" />
            </el-form-item>
            <el-form-item label="身份证号" prop="idcard">
                <el-input v-model.trim="ruleForm.idcard" placeholder="请输入身份证号" />
            </el-form-item>
            <el-form-item label="登录密码" prop="password" v-if="props.currentType == 'add'">
                <el-input v-model.trim="ruleForm.password" placeholder="请输入登录密码" type='password' show-password />
            </el-form-item>
            <el-form-item label="所属部门" prop="depIdArr">
                <el-cascader :options="departmentOptions" v-model="ruleForm.depIdArr" clearable style="width: 100%;" />
            </el-form-item>
            <el-form-item label="出生日期" prop="birthdate">
                <el-date-picker v-model.trim="ruleForm.birthdate" type="date" readonly placeholder="请选择出生日期(从身份证中获取)"
                    style="width:100%" :value-format="'YYYY-MM-DD'" />
            </el-form-item>
            <el-form-item label="性别" prop="sex">
                <el-radio-group v-model="ruleForm.sex">
                    <el-radio :label="1">男</el-radio>
                    <el-radio :label="0">女</el-radio>
                </el-radio-group>
            </el-form-item>
        </el-form>
    </zt-dialog>
</template>

<script setup>
import ztDialog from '@/components/zt-dialog/index.vue'
import { ElMessage } from 'element-plus'
import { apiPostCreateUser, apiPutUpdateUser } from "@/api/admin/systemSettings/accountManage/api.js"
import { apiGetDepartmentTree } from "@/api/common/api.js"

const isLoading = ref(false)
const departmentOptions = ref([])

const emit = defineEmits(['success', 'update:modelValue'])
const props = defineProps({
    // 当前类型
    currentType: {
        type: String,
        default: 'add'
    },
    // 控制弹窗显示
    visible: {
        type: Boolean,
        default: false
    },
    // 传递过来的值
    objectValue: {
        type: Object,
        default: () => {
            return {}
        }
    }
})

const ruleFormRef = ref(null)
const ruleForm = reactive({
    userName: '',// 用户名称
    mobile: '',// 手机号
    accountName: '',// 登录账号
    password: '',// 登录密码
    idcard: '',// 身份证号
    sex: 1,//性别(代码 0:女/1:男)
    birthdate: '',//出生日期
    depIdArr: '',// 部门id数组
    depId: '',// 部门id
})
const updateForm = reactive({
    userId: '',// 用户id
})

const rules = reactive({
    userName: [
        { required: true, message: '请输入用户名称', trigger: 'blur' },
    ],
    mobile: [
        { required: true, message: '请输入手机号', trigger: 'blur' },
        {
            pattern: /^1[3456789]\d{9}$/,
            message: '手机号格式不正确',
            trigger: 'change',
        },
    ],
    accountName: [
        { required: true, message: '请输入登录名称', trigger: 'blur' },
    ],
    password: [
        { required: true, message: '请输入登录密码', trigger: 'change' },
        { min: 6, message: '密码长度不能少于6位', trigger: 'change' },
        {
            validator: (rule, value) => {
                if (value && /[\u4e00-\u9fa5]/.test(value)) {
                    return Promise.reject('密码不能包含中文字符');
                }
                return Promise.resolve();
            },
            trigger: 'change',
        },
    ],
    idcard: [
        { required: true, message: '请输入身份证号', trigger: 'blur' },
        {
            validator: (rule, value, callback) => {
                if (value) {
                    // 15位和18位身份证号码的正则表达式
                    var idCardReg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
                    // 如果通过该验证，说明身份证格式正确，但准确性还需计算
                    if (idCardReg.test(value)) {
                        if (value.length == 18) {
                            const idCardWi = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); // 将前17位加权因子保存在数组里
                            const idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); // 这是除以11后，可能产生的11位余数、验证码，也保存成数组
                            let idCardWiSum = 0; // 用来保存前17位各自乖以加权因子后的总和
                            for (var i = 0; i < 17; i++) {
                                idCardWiSum += value.substring(i, i + 1) * idCardWi[i];
                            }
                            var idCardMod = idCardWiSum % 11; // 计算出校验码所在数组的位置
                            var idCardLast = value.substring(17); // 得到最后一位身份证号码
                            // 如果等于2，则说明校验码是10，身份证号码最后一位应该是X
                            if (idCardMod == 2) {
                                if (idCardLast == 'X' || idCardLast == 'x') {
                                    callback();
                                } else {
                                    callback('请输入正确身份证号码');
                                }
                            } else {
                                // 用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                                if (idCardLast == idCardY[idCardMod]) {
                                    callback();
                                } else {
                                    callback('请输入正确身份证号码');
                                }
                            }
                        }
                    } else {
                        callback('请输入正确身份证号码');
                    }
                } else {
                    callback();
                }
            },
            trigger: 'change',
        },
    ],
    sex: [
        {
            required: true,
            message: '请选择性别',
            trigger: 'change',
        },
    ],
    depIdArr: [
        {
            required: true,
            message: '请选择部门',
            trigger: 'change',
        },
    ],
})


// 动态获取标题
const titleName = computed(() => {
    switch (props.currentType) {
        case 'edit':
            return '修改账号'
        case 'add':
            return '添加账号'
        case 'detail':
            return '详情'
    }
})

// 是否禁用表单
const isDisabled = computed(() => {
    return props.currentType == 'detail' ? true : false
})

// 子组件定义自己的visible
const visible = computed({
    get: () => props.visible,
    set: (value) => {
        // 清除表单字段值
        Object.keys(ruleForm).forEach(key => {
            if (key == 'sex') {
                ruleForm[key] = 1 //默认设置为男
            } else {
                ruleForm[key] = '';
            }
        });
        ruleFormRef.value.clearValidate()
        emit('update:modelValue', value)
    },
})

// 监听传递过来的值 赋值
watch(() => props.objectValue, (e) => {
    if (e) {
        if (props.currentType != 'add') {
            // 遍历 key 相等的赋值 
            Object.keys(e).forEach(item => {
                Object.keys(ruleForm).forEach(ele => {
                    if (item == ele) {
                        ruleForm[ele] = e[item]
                    }
                });
            });
            updateForm.userId = e.userId
        }
    }
}, {
    deep: true,
    immediate: true
})


// 监听身份证号输入框 获取出生年月
watch(
    () => ruleForm.idcard,
    (val) => {
        ruleForm.birthdate = getBirthdayFromIdCard(val)
    },
)

// 根据身份证号获取出生年月
function getBirthdayFromIdCard(idCard) {
    let birthday = ''
    if (idCard !== null && idCard !== '' && idCard.length === 18) {
        birthday = idCard.substr(6, 8)
        birthday = birthday.replace(/(.{4})(.{2})/, '$1-$2-')
    }
    return birthday
}

// 确认按钮
async function confirmBtn() {
    if (!ruleFormRef.value) return
    await ruleFormRef.value.validate((valid, fields) => {
        if (valid) {
            ruleForm.depId = ruleForm.depIdArr[ruleForm.depIdArr.length - 1]
            delete ruleForm.depIdArr //这个不需要传递 所以删除

            // 编辑时执行
            if (props.currentType == 'edit') {
                editChange()
            }

            // 添加时执行
            if (props.currentType == 'add') {
                addChange()
                return false
            }

        } else {
            const firstValue = Object.values(fields)[0];
            ElMessage({
                message: firstValue[0].message,
                type: 'warning',
            })
        }
    })
}

// 添加方法
function addChange() {
    isLoading.value = true
    apiPostCreateUser(ruleForm).then(res => {
        if (res.success) {
            ElMessage({
                message: '添加成功',
                type: 'success',
            })
            emit('success')
            visible.value = false
            return false
        }
        ElMessage({
            message: res.message,
            type: 'warning',
        })
    }).finally(() => {
        isLoading.value = false
    })
}

// 编辑方法
function editChange() {
    isLoading.value = true
    apiPutUpdateUser({ ...ruleForm, ...updateForm }).then(res => {
        if (res.success) {
            ElMessage({
                message: '修改成功',
                type: 'success',
            })
            emit('success')
            visible.value = false
            return false
        }
        ElMessage({
            message: res.message,
            type: 'warning',
        })
    }).finally(() => {
        isLoading.value = false
    })
}

// 获取部门列表树数据
function getDeptTreeData() {
    apiGetDepartmentTree({}).then(res => {
        if (res.success) {
            departmentOptions.value = convertToOptions(res.data)

            if (props.currentType != 'add' && ruleForm.depId) {
                let list = convertToOptions(res.data)
                ruleForm.depIdArr = getAllParentValues(list, ruleForm.depId).reverse()
            }
        }
    })
}
// 处理数据
function convertToOptions(data) {
    const options = [];
    function traverse(node) {
        const option = {
            value: node.depId,
            label: node.depName,
            parentId: node.parentId,
        };
        if (node.children && node.children.length > 0) {
            option.children = node.children.map(child => traverse(child));
        }
        return option;
    }
    options.push(traverse(data));
    return options;
}
// 数据处理
function getAllParentValues(arrs, value) {
    for (let i = 0; i < arrs.length; i++) {
        const item = arrs[i];
        if (item.children) {
            // 如果当前节点有子节点，则递归查找子节点
            const parentValues = getAllParentValues(item.children, value);
            if (parentValues.length > 0) {
                // 如果找到了对应的父级value值，则将当前节点的value值添加到父级value值数组中
                parentValues.push(item.value);
                return parentValues;
            }
        }
        if (item.value === value) {
            // 如果当前节点的value值等于目标值，则返回当前节点的value值
            return [item.value];
        }
    }
    // 如果未找到对应的父级value值，则返回空数组
    return [];
}


getDeptTreeData()

</script>

<style lang='scss' scoped></style>
<style lang="scss">
.el-input__wrapper {
    width: 100%;
}
</style>